﻿using System.Collections.Generic;
using System.Linq;
using CID.Domain.Development;
using CID.Execution.Controller.Support;
using NUnit.Framework;

namespace CID.Execution.Controller.Tests.Support
{
    [TestFixture]
    class ComponentDependencyResolverTests : BaseControllerTests
    {
        private List<IVersion> affectedVersions;
        private ComponentDependencyResolver dependencyResolver;

        public override void SetUp()
        {
            base.SetUp();
            affectedVersions = new List<IVersion>();
            affectedVersions.AddRange(DevelopmentData.ActiveRelease.Versions);
            affectedVersions.AddRange(OperationsData.Environment.ActiveVersions.Select(x => x.Version).Where(
                x => !affectedVersions.Select(y => y.Component).Contains(x.Component)));
            dependencyResolver = new ComponentDependencyResolver(affectedVersions);
        }

        [Test]
        public void TestGetDeactivationSequence_ShouldReturnDependeciesSortInPostOrder()
        {
            var sequence = dependencyResolver.GetDeactivationSequence().ToList();

            foreach (var component in sequence)
                foreach (var dependant in component.Dependants.Select(x => x.Component))
                    AssertDeactivatesBeforeThan(sequence, dependant, component);
        }

        private void AssertDeactivatesBeforeThan(List<IComponent> sequence, IComponent dependant, IComponent dependency)
        {
            Assert.Less(sequence.IndexOf(dependant), sequence.IndexOf(dependency));
        }

        [Test]
        public void TestGetActivationSequence_ShouldReturnDependeciesSortInReversePostOrder()
        {
            var sequence = dependencyResolver.GetActivationSequence().ToList();

            foreach (var component in sequence)
                foreach (var dependant in component.Dependants.Select(x => x.Component))
                    AssertActivatesBeforeThan(sequence, component, dependant);
        }

        private void AssertActivatesBeforeThan(List<IComponent> sequence, IComponent dependency, IComponent dependant)
        {
            Assert.Less(sequence.IndexOf(dependency), sequence.IndexOf(dependant));
        }
    }
}
